/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs     (C)ChaN, 2025        */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be        */
/* attached to the FatFs via a glue function rather than modifying it.   */
/* This is an example of glue functions to attach various exsisting      */
/* storage control modules to the FatFs module with a defined API.       */
/*-----------------------------------------------------------------------*/

#include "ff.h"			/* Basic definitions of FatFs */
#include "diskio.h"		/* Declarations FatFs MAI */

/* Example: Declarations of the platform and disk functions in the project */
#include "stdio.h"
#include "../sdcard/include/spi_sdcard.h"

/* Example: Mapping of physical drive number for each drive */
#define SD_CARD 0 /* SD 卡,卷标为 0 */


/*-----------------------------------------------------------------------*/
/* Get Drive Status                                                      */
/*-----------------------------------------------------------------------*/

DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber to identify the drive */
)
{
	return RES_OK;
}



/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{
	int res;
	switch (pdrv)
	{
		case SD_CARD:
			res = sd_init(); /* SD 卡初始化 */
			break;
		default:
			res = 1;
	}
	if(res == SD_OK) return RES_OK;
	else return RES_ERROR;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/

DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
	BYTE *buff,		/* Data buffer to store read data */
	LBA_t sector,	/* Start sector in LBA */
	UINT count		/* Number of sectors to read */
)
{
	int res;

	if (!count)
		return RES_PARERR; /* count 不能等于 0，否则返回参数错误 */

	switch (pdrv)
	{
		case SD_CARD:
		{
			printf("disk_read 每次读的扇区数量 = %d \r\n", count);
			res = sd_read_disk(buff, sector, count);
			while (res) /* 读出错 */
			{
				sd_init(); /* 重新初始化 SD 卡 */
				res = sd_read_disk(buff, sector, count);
			}
			break;
		}
		default:
			res = 1;
	}
	/* 处理返回值，将返回值转成 ff.c 的返回值 */
	if(res == SD_OK) return RES_OK;
	else return RES_ERROR;
}




/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/

#if FF_FS_READONLY == 0

DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
	const BYTE *buff,	/* Data to be written */
	LBA_t sector,		/* Start sector in LBA */
	UINT count			/* Number of sectors to write */
)
{
	int res = 0;
	if (!count)
		return RES_PARERR; /* count 不能等于 0，否则返回参数错误 */

	switch (pdrv)
	{
		case SD_CARD: /* SD 卡 */
			res = sd_write_disk((uint8_t *)buff, sector, count);
			while (res) /* 写出错 */
			{
				sd_init(); /* 重新初始化 SD 卡 */
				res = sd_write_disk((uint8_t *)buff, sector, count);
			}
			break;
		default:
			res = 1;
	}
	/* 处理返回值，将返回值转成 ff.c 的返回值 */ 
	if(res == SD_OK) return RES_OK;
	else return RES_ERROR;
}

#endif


/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/

DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	int res; 
	if (pdrv == SD_CARD) /* SD 卡 */ 
	{ 
		switch (cmd) 
		{ 
			case CTRL_SYNC: 
				res = RES_OK; 
				break; 			
			case GET_SECTOR_SIZE:      /*获取扇区大小*/
				*(DWORD *)buff = 512; 
				res = RES_OK; 
				break;
			case GET_BLOCK_SIZE: 	   /*获取块大小*/
				*(WORD *)buff = 8; 
				res = RES_OK; 
				break; 
			
			case GET_SECTOR_COUNT:     /*获取扇区数量*/
				*(DWORD *)buff = sd_get_sector_count(); 
				res = RES_OK; 
				break; 
			
			default: 
				res = RES_PARERR; 
				break; 
		} 
	}
	else 
	{ 
		res = RES_ERROR; /* 其他的不支持 */ 
	} 
	
	return res;			
}

